"""Pydantic models for API requests and responses."""

from typing import List, Dict, Any, Optional
from pydantic import BaseModel, Field
from datetime import datetime


class EmbeddingRequest(BaseModel):
    """Request model for text embedding."""
    texts: List[str] = Field(..., description="List of texts to embed")
    provider: Optional[str] = Field(None, description="Embedding provider to use")


class EmbeddingResponse(BaseModel):
    """Response model for text embedding."""
    embeddings: List[List[float]] = Field(..., description="List of embedding vectors")
    provider: str = Field(..., description="Provider used for embedding")
    model: str = Field(..., description="Model used for embedding")
    dimensions: int = Field(..., description="Vector dimensions")


class VectorStoreRequest(BaseModel):
    """Request model for storing vectors."""
    table_name: str = Field(..., description="Table name to store vectors in")
    vectors: Optional[List[List[float]]] = Field(None, description="Optional pre-computed vectors")
    texts: List[str] = Field(..., description="Texts to store (will be embedded if vectors not provided)")
    metadata: Optional[List[Dict[str, Any]]] = Field(None, description="Optional metadata for each text")
    provider: Optional[str] = Field(None, description="Embedding provider to use")


class VectorSearchRequest(BaseModel):
    """Request model for vector search."""
    table_name: str = Field(..., description="Table name to search in")
    query: str = Field(..., description="Query text to search for")
    limit: int = Field(10, ge=1, le=100, description="Maximum number of results")
    threshold: float = Field(0.0, ge=0.0, le=1.0, description="Similarity threshold (0.0 = no threshold)")
    provider: Optional[str] = Field(None, description="Embedding provider to use for query")


class VectorSearchResponse(BaseModel):
    """Response model for vector search."""
    results: List[Dict[str, Any]] = Field(..., description="Search results")
    count: int = Field(..., description="Number of results returned")
    query: str = Field(..., description="Original query text")
    table_name: str = Field(..., description="Table searched")


class VectorDeleteRequest(BaseModel):
    """Request model for deleting vectors."""
    table_name: str = Field(..., description="Table name to delete from")
    conditions: Dict[str, Any] = Field(..., description="Deletion conditions")


class TableCreateRequest(BaseModel):
    """Request model for creating tables."""
    table_name: str = Field(..., description="Name of the table to create")
    vector_dimension: int = Field(1024, ge=1, description="Vector dimension")
    overwrite: bool = Field(False, description="Whether to overwrite existing table")


class TableInfoResponse(BaseModel):
    """Response model for table information."""
    name: str = Field(..., description="Table name")
    schema: str = Field(..., description="Table schema")
    row_count: int = Field(..., description="Number of rows in table")
    created_at: Optional[str] = Field(None, description="Table creation time")


class DatabaseStatsResponse(BaseModel):
    """Response model for database statistics."""
    uri: str = Field(..., description="Database URI")
    total_tables: int = Field(..., description="Total number of tables")
    tables: Dict[str, Dict[str, Any]] = Field(..., description="Table statistics")
    pool_stats: Dict[str, int] = Field(..., description="Connection pool statistics")


class HealthResponse(BaseModel):
    """Response model for health check."""
    status: str = Field(..., description="Service status")
    timestamp: datetime = Field(..., description="Health check timestamp")
    database: Dict[str, Any] = Field(..., description="Database health info")
    embedding: Dict[str, Any] = Field(..., description="Embedding service health info")


class ProviderInfoResponse(BaseModel):
    """Response model for provider information."""
    available_providers: List[str] = Field(..., description="List of available providers")
    current_provider: Optional[str] = Field(None, description="Currently active provider")
    provider_configs: Dict[str, Dict[str, Any]] = Field(..., description="Provider configurations")


class ErrorResponse(BaseModel):
    """Response model for errors."""
    error: str = Field(..., description="Error message")
    detail: Optional[str] = Field(None, description="Detailed error information")
    timestamp: datetime = Field(default_factory=datetime.now)


class SuccessResponse(BaseModel):
    """Response model for successful operations."""
    status: str = Field("success", description="Operation status")
    message: str = Field(..., description="Success message")
    timestamp: datetime = Field(default_factory=datetime.now)


class WebSocketMessage(BaseModel):
    """WebSocket message model."""
    type: str = Field(..., description="Message type")
    data: Optional[Dict[str, Any]] = Field(None, description="Message data")
    request_id: Optional[str] = Field(None, description="Request ID for correlation")


class RagQueryRequest(BaseModel):
    """Request model for RAG queries."""
    query: str = Field(..., description="User query")
    table_name: str = Field("documents", description="Table to search in")
    limit: int = Field(5, ge=1, le=20, description="Number of context documents")
    threshold: float = Field(0.0, ge=0.0, le=1.0, description="Similarity threshold")
    provider: Optional[str] = Field(None, description="Embedding provider")


class RagQueryResponse(BaseModel):
    """Response model for RAG queries."""
    query: str = Field(..., description="Original query")
    context: List[Dict[str, Any]] = Field(..., description="Retrieved context documents")
    context_count: int = Field(..., description="Number of context documents")
    table_name: str = Field(..., description="Table searched")